﻿using System;
using System.Collections.Generic;
using System.Linq;
using Assist;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using Autodesk.Revit.UI.Selection;
using YArchitech.Revit;
using YJKRevitDimension.DetailIndex.Manager;
using YJKGeometryFuncs;

namespace YJKRevitDimension.DetailIndex.Operate
{
	internal class DetailIndexOperateBase
	{
		public List<ElementId> TempElementIds { get; set; }

		public DetailIndexParameter m_DetailIndexParameter { get; set; }

		public bool IfUseCustomAngle { get; set; }

		public DetailIndexOperateBase(ExternalCommandData revit, DetailIndexParameter detailIndexPara)
		{
			this.IfUseCustomAngle = detailIndexPara.IsFixedAngle;
			this.Angle = detailIndexPara.Angle;
			this.m_DetailIndexParameter = detailIndexPara;
			this.TempElementIds = new List<ElementId>();
			this.m_Revit = revit;
			this.m_UIDoc = revit.Application.ActiveUIDocument;
			this.m_Doc = revit.Application.ActiveUIDocument.Document;
			this.m_Selection = this.m_UIDoc.Selection;
			this.m_ViewScale = (double)this.m_UIDoc.ActiveView.Scale;
			this.m_SourceFamilyDocPath = Utility.GetFamilyFileName(this.m_Doc, detailIndexPara.Type);
		}

		public bool GetForward(XYZ startPoint, XYZ endPoint)
		{
			Autodesk.Revit.DB.View activeView = this.m_Doc.ActiveView;
			double val = (endPoint - startPoint).Normalize().DotProduct(activeView.RightDirection);
			return Geometry.LessThan(0.0, val);
		}

		public bool GetFamilySymbol(out FamilySymbol fs)
		{
			string text = "索引标注";
			string text2 = "索引标注-圆";
			Family family;
			if (this.m_TargetFamilyDocPath.Contains("HY-IndexMarkCircle"))
			{
				family = ElementFiltering.FindFamily(this.m_Doc, text2);
			}
			else
			{
				family = ElementFiltering.FindFamily(this.m_Doc, text);
			}
			if (family != null)
			{
				fs = family.GetSymbols().FirstOrDefault<FamilySymbol>();
				return true;
			}
			if (this.m_DetailIndexParameter.IsForward)
			{
                if (!this.m_Doc.LoadFamilySymbol(this.m_TargetFamilyDocPath, "标注右", out fs))
				{
					return false;
				}
			}
            else if (!this.m_Doc.LoadFamilySymbol(this.m_TargetFamilyDocPath, "标注左", out fs))
			{
				return false;
			}
			if (this.m_TargetFamilyDocPath.Contains("HY-IndexMarkCircle"))
			{
				fs.Family.Name = text2;
			}
			else
			{
				fs.Family.Name = text;
			}
			return true;
		}

		public XYZ GetSliceNormal(XYZ startPoint, XYZ endPoint, XYZ slicePoint)
		{
			XYZ xyz = endPoint - startPoint;
			XYZ xyz2;
			if (this.GetSliceDirection(startPoint, endPoint, slicePoint))
			{
				if (this.GetForward(startPoint, endPoint))
				{
					xyz2 = Transform.CreateRotation(this.m_Doc.ActiveView.ViewDirection, Math.PI*.5).OfVector(xyz);
				}
				else
				{
					xyz2 = Transform.CreateRotation(this.m_Doc.ActiveView.ViewDirection, -Math.PI*.5).OfVector(xyz);
				}
			}
			else if (this.GetForward(startPoint, endPoint))
			{
				xyz2 = Transform.CreateRotation(this.m_Doc.ActiveView.ViewDirection, -Math.PI*.5).OfVector(xyz);
			}
			else
			{
				xyz2 = Transform.CreateRotation(this.m_Doc.ActiveView.ViewDirection, Math.PI*.5).OfVector(xyz);
			}
			return xyz2.Normalize();
		}

		private bool GetSliceDirection(XYZ startPoint, XYZ endPoint, XYZ slicePoint)
		{
			XYZ xyz = endPoint - startPoint;
			XYZ xyz2 = slicePoint - startPoint;
			XYZ xyz3 = this.m_Doc.ActiveView.ViewDirection;
			if (!this.GetForward(startPoint, endPoint))
			{
				xyz3 = -xyz3;
			}
			return Geometry.LessThan(xyz.AngleOnPlaneTo(xyz2, xyz3), Math.PI);
		}

		public bool ModifyFamilyInstancePara(ref FamilyInstance fs)
		{
			bool result;
			try
			{
				XYZ xyz = (this.m_DetailIndexParameter.StartPoint - this.m_DetailIndexParameter.ElbowPoint).Normalize();
				double num = this.m_Doc.ActiveView.RightDirection.AngleOnPlaneTo(xyz, -this.m_Doc.ActiveView.ViewDirection);
				double num2 = this.m_DetailIndexParameter.StartPoint.DistanceTo(this.m_DetailIndexParameter.ElbowPoint) / this.m_ViewScale;
				fs.GetParameter("详图编号").Set(this.m_DetailIndexParameter.IndexSymbolID);
				if (this.m_DetailIndexParameter.IndexSymbolID == "")
				{
					fs.GetParameter("参数1").Set(0);
				}
				fs.GetParameter("图纸编号").Set(this.m_DetailIndexParameter.IndexSymbolDrawingID);
				if (this.m_DetailIndexParameter.IndexSymbolDrawingID == "")
				{
					fs.GetParameter("参数2").Set(0);
				}
				fs.GetParameter("文字1").Set(this.m_DetailIndexParameter.SuperScriptText);
				if (this.m_DetailIndexParameter.SuperScriptText == "")
				{
					fs.GetParameter("参数3").Set(0);
				}
				fs.GetParameter("文字2").Set(this.m_DetailIndexParameter.DownScriptText);
				if (this.m_DetailIndexParameter.DownScriptText == "")
				{
					fs.GetParameter("参数4").Set(0);
				}
				fs.GetParameter("尺寸").Set(this.m_DetailIndexParameter.BaseLineLength);
				fs.GetParameter("长度").Set(num2);
				fs.GetParameter("角度").Set(num);
				if (this.m_DetailIndexParameter.Type == DetailIndexType.RangeDirectIndex)
				{
					double num3 = this.m_DetailIndexParameter.StartPoint.DistanceTo(this.m_DetailIndexParameter.MiddlePoint) / this.m_ViewScale;
					fs.GetParameter("索引半径").Set(num3);
					fs.GetParameter("长度").Set(num2 - num3);
				}
				result = true;
			}
			catch (Exception)
			{
				result = false;
			}
			return result;
		}

		public void UpdateDetailIndexParameter(DetailIndexParameter para)
		{
			this.m_DetailIndexParameter.IndexSymbolID = para.IndexSymbolID;
			this.m_DetailIndexParameter.IndexSymbolDrawingID = para.IndexSymbolDrawingID;
			this.m_DetailIndexParameter.SuperScriptText = para.SuperScriptText;
			this.m_DetailIndexParameter.DownScriptText = para.DownScriptText;
			this.m_DetailIndexParameter.IsFixedAngle = para.IsFixedAngle;
			this.m_DetailIndexParameter.Angle = para.Angle;
		}

		private XYZ GetVerticalVec(Autodesk.Revit.DB.View view, XYZ hVec)
		{
			Transform transform;
			if (this.GetSliceDirection(this.m_DetailIndexParameter.StartPoint, this.m_DetailIndexParameter.ElbowPoint, this.m_DetailIndexParameter.SlicePoint))
			{
				if (this.GetForward(this.m_DetailIndexParameter.StartPoint, this.m_DetailIndexParameter.ElbowPoint))
				{
					transform = Transform.CreateRotation(view.ViewDirection, -Math.PI*.5);
				}
				else
				{
					transform = Transform.CreateRotation(view.ViewDirection, Math.PI*.5);
				}
			}
			else if (this.GetForward(this.m_DetailIndexParameter.StartPoint, this.m_DetailIndexParameter.ElbowPoint))
			{
				transform = Transform.CreateRotation(view.ViewDirection, Math.PI*.5);
			}
			else
			{
				transform = Transform.CreateRotation(view.ViewDirection, -Math.PI*.5);
			}
			return transform.OfVector(hVec);
		}

		public bool CreateFilledRegion(XYZ inputOrigin, double offset, Autodesk.Revit.DB.Document doc, Autodesk.Revit.DB.View view, ref ElementId eleId, double scale = 1.0, bool isCreateInCurrentDoc = false)
		{
			bool result;
			try
			{
				XYZ xyz = (this.m_DetailIndexParameter.StartPoint - this.m_DetailIndexParameter.ElbowPoint).Normalize();
				double num = this.m_Doc.ActiveView.RightDirection.AngleOnPlaneTo(xyz, -this.m_Doc.ActiveView.ViewDirection);
				XYZ xyz2 = Transform.CreateRotation(-view.ViewDirection, num).OfVector(view.RightDirection);
				XYZ verticalVec = this.GetVerticalVec(view, xyz2);
				XYZ xyz3 = new XYZ();
				if (isCreateInCurrentDoc)
				{
					xyz3 = inputOrigin;
				}
				else
				{
					xyz3 = view.Origin;
				}
				XYZ xyz4 = xyz3.Add(xyz2 * offset * scale).Add(verticalVec * DetailIndexOperateBase.m_Offset * scale);
				XYZ xyz5 = xyz4.Add(-xyz2 * DetailIndexOperateBase.m_Legth * scale);
				XYZ xyz6 = xyz5.Add(verticalVec * DetailIndexOperateBase.m_Height * scale);
				XYZ xyz7 = xyz4.Add(verticalVec * DetailIndexOperateBase.m_Height * scale);
				CurveLoop curveLoop = new CurveLoop();
				curveLoop.Append(Line.CreateBound(xyz4, xyz5));
				curveLoop.Append(Line.CreateBound(xyz5, xyz6));
				curveLoop.Append(Line.CreateBound(xyz6, xyz7));
				curveLoop.Append(Line.CreateBound(xyz7, xyz4));
				IList<CurveLoop> list = new List<CurveLoop>();
				list.Add(curveLoop);
				ElementId regionType = this.GetRegionType(doc, Shape.Square);
				eleId = FilledRegion.Create(doc, regionType, view.Id, list).Id;
				result = true;
			}
			catch (Exception)
			{
				result = false;
			}
			return result;
		}

		public ElementId GetRegionType(Autodesk.Revit.DB.Document doc, Shape fillShape)
		{
			FilteredElementCollector filteredElementCollector = new FilteredElementCollector(doc);
			filteredElementCollector.OfClass(typeof(FilledRegionType));
			FilledRegionType filledRegionType = null;
			foreach (Element element in filteredElementCollector)
			{
				FilledRegionType filledRegionType2 = element as FilledRegionType;
				if (filledRegionType2 != null)
				{
					if (fillShape != Shape.Square)
					{
						if (fillShape == Shape.Circle)
						{
							if (filledRegionType2.Name == DetailIndexOperateBase.m_FilledRegionCircleTypeName)
							{
								filledRegionType = filledRegionType2;
							}
						}
					}
					else if (filledRegionType2.Name == DetailIndexOperateBase.m_FilledRegionSquareTypeName)
					{
						filledRegionType = filledRegionType2;
					}
				}
			}
			if (filledRegionType == null)
			{
				FilledRegionType filledRegionType2 = filteredElementCollector.ToElements().First<Element>() as FilledRegionType;
				if (fillShape != Shape.Square)
				{
					if (fillShape == Shape.Circle)
					{
						filledRegionType = (filledRegionType2.Duplicate(DetailIndexOperateBase.m_FilledRegionCircleTypeName) as FilledRegionType);
						filledRegionType.GetParameter("颜色").Set(16777215);
					}
				}
				else
				{
					filledRegionType = (filledRegionType2.Duplicate(DetailIndexOperateBase.m_FilledRegionSquareTypeName) as FilledRegionType);
					filledRegionType.GetParameter("颜色").Set(0);
				}
				if (filledRegionType == null)
				{
					return null;
				}
				filledRegionType.GetParameter(BuiltInParameter.FILL_PATTERN_ID_PARAM_NO_NO).Set(this.GetFillPatternElementID(doc));
			}
			return filledRegionType.Id;
		}

		private ElementId GetFillPatternElementID(Autodesk.Revit.DB.Document doc)
		{
			FilteredElementCollector filteredElementCollector = new FilteredElementCollector(doc);
			filteredElementCollector.OfClass(typeof(FillPatternElement));
			foreach (Element element in filteredElementCollector)
			{
				FilledRegionType filledRegionType = element as FilledRegionType;
				if (filledRegionType != null && filledRegionType.Name == DetailIndexOperateBase.m_FillPatternElmentName)
				{
					return filledRegionType.Id;
				}
			}
			ElementId result;
			try
			{
				result = filteredElementCollector.ToElements().First<Element>().Id;
			}
			catch (Exception)
			{
				result = null;
			}
			return result;
		}

		public bool CreateFamilySymbol()
		{
			Transaction transaction = new Transaction(this.m_Doc, "Create Detail Index");
			try
			{
                if (1 != (int)transaction.Start())
				{
					return false;
				}
				if ("" == this.m_TargetFamilyDocPath)
				{
					return false;
				}
				FamilySymbol familySymbol;
				if (!this.GetFamilySymbol(out familySymbol))
				{
					transaction.RollBack();
					return false;
				}
				FamilyInstance familyInstance = this.m_Doc.Create.NewFamilyInstance(this.m_DetailIndexParameter.ElbowPoint, familySymbol, this.m_Doc.ActiveView);
				transaction.Commit();
				transaction.Start();
				if (!Geometry.IsEqual(this.m_Doc.ActiveView.UpDirection, familyInstance.FacingOrientation.Normalize(), 0.0001) && !Geometry.IsEqual(this.m_Doc.ActiveView.RightDirection, familyInstance.FacingOrientation.Normalize(), 0.0001))
				{
					Line line = Line.CreateBound(this.m_DetailIndexParameter.ElbowPoint, this.m_DetailIndexParameter.ElbowPoint.Add(this.m_Doc.ActiveView.ViewDirection * 10.0));
					ElementTransformUtils.RotateElement(this.m_Doc, familyInstance.Id, line, Math.PI);
				}
				this.ModifyFamilyInstancePara(ref familyInstance);
				transaction.Commit();
			}
			catch (Exception)
			{
				transaction.RollBack();
				return false;
			}
			return true;
		}

		public bool DeleteTempElement()
		{
			if (this.TempElementIds.Count == 0)
			{
				return true;
			}
			if (this.TempElementIds.Count > 0)
			{
				Transaction transaction = new Transaction(this.m_Doc, "Delete TempElement");
				try
				{
					transaction.Start();
					this.m_Doc.Delete(this.TempElementIds);
					transaction.Commit();
				}
				catch (Exception)
				{
					transaction.RollBack();
					return false;
				}
				return true;
			}
			return true;
		}

		public ExternalCommandData m_Revit;

		public UIDocument m_UIDoc;

		public Selection m_Selection;

		public Document m_Doc;

		public double m_ViewScale;

		public string m_SourceFamilyDocPath;

		public string m_TargetFamilyDocPath;

		public static double m_Offset = 0.0041010498687664041;

		public static double m_Height = 0.0026246719160104987;

		public static double m_Legth = 0.016404199475065617;

		public static double m_Radis = 0.016404199475065617;

		public static string m_FilledRegionSquareTypeName = "IndexMarkSquare";

		public static string m_FilledRegionCircleTypeName = "IndexMarkCircle";

		public static string m_FillPatternElmentName = "填充样式";

		public double Angle;
	}
}
